import { useState } from 'react';
import styled from 'styled-components';
import SearchFile from './components/SearchFile';
import FileList from './components/FileList';
import ButtonItem from './components/ButtonItem';
import TabList from './components/TabList';
import { faFileImport, faPlus } from '@fortawesome/free-solid-svg-icons';
import SimpleMDE from 'react-simplemde-editor';
import { v4 } from 'uuid';
import { mapArr, objToArr, readFile, writeFile, deleteFile, renameFile } from './utils/helper';
import 'easymde/dist/easymde.min.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import useIpcRenderer from './hooks/useIpcRenderer';

const path = window.require('path');
const remote = window.require('@electron/remote');
const Store = window.require('electron-store');
// const { ipcRenderer } = window.require('electron');

const fileStore = new Store({ name: 'filesInfo' });

// 实现具体属性的持久化存储
const saveInfoToStore = files => {
  const storeObj = objToArr(files).reduce((ret, file) => {
    const { id, title, createTime, path } = file;
    ret[id] = {
      id,
      path,
      title,
      createTime
    };
    return ret;
  }, {});
  fileStore.set('files', storeObj);
};

function App() {
  const [files, setFiles] = useState(fileStore.get('files') || {}); // 所有的文件信息
  const [activId, setActiveId] = useState(''); // 当前正在编辑的文件id
  const [openIds, setOpenIds] = useState([]); // 当前已打开的问文件id
  const [unSaveIds, setUnSaveIds] = useState([]); //当前未被保存的id
  const [searchFiles, setSearchFiles] = useState([]); // 左侧展示的搜索列表与默认列表信息进行区分

  // 自定义一个当前磁盘里存放的文件路径
  const savedPath = remote.app.getPath('desktop') + '/demo';
  // console.log(remote.app.getPath('userData'));
  // 已打开的所有文件信息
  const openFiles = openIds.map(openId => {
    return files[openId];
  });

  // 正在编辑的文件信息
  const activeFile = files[activId];

  // 计算当前左侧列表需要展示什么样信息
  const fileList = searchFiles.length > 0 ? searchFiles : objToArr(files);

  // 点击左侧文件显示编辑页
  const openItem = id => {
    // 将当前id 设置为 active id
    setActiveId(id);
    // 点击某个文件时 读取内容
    const currentFile = files[id];
    if (!currentFile.isLoaded) {
      readFile(currentFile.path).then(data => {
        const newFile = { ...currentFile, body: data, isLoaded: true };
        setFiles({ ...files, [id]: newFile });
      });
    }
    // 将id加入
    if (!openIds.includes(id)) setOpenIds([...openIds, id]);
  };

  // 切换tab
  const changeActive = id => {
    setActiveId(id);
  };

  // tab 点击关闭
  const closeFile = id => {
    // 将当前id 从已经打开的id 中 删除
    const retOpen = openIds.filter(openId => openId !== id);
    setOpenIds(retOpen);
    // 当某一个选项被关闭之后 需要设置一个当前状态
    if (retOpen.length > 0 && activId === id) {
      setActiveId(retOpen[0]);
    } else if (retOpen.length > 0 && activId !== id) {
      // 如果关闭的不是当前 选中的tab 还需要接着显示原先的tab
      setActiveId(activId);
    } else {
      setActiveId('');
    }
  };

  // 当文件内容更新是
  const changeFile = (id, newValue) => {
    if (newValue !== files[id].body) {
      if (!unSaveIds.includes(id)) {
        setUnSaveIds([...unSaveIds, id]);
      }
      // 某个内容更新后 需要生成一个新的files
      const newFile = { ...files[id], body: newValue };
      setFiles({ ...files, [id]: newFile });
    }
  };

  // 删除文件
  const deleteItem = id => {
    const file = files[id];
    if (!file.isNew) {
      deleteFile(file.path).then(() => {
        delete files[id];
        setFiles(files);
        saveInfoToStore(files);
        closeFile(id); // 如果删除的文件 已经打开 需要处理tab
      });
    } else {
      delete files[id];
      setFiles(files);
      saveInfoToStore(files);
      closeFile(id); // 如果删除的文件 已经打开 需要处理tab
    }
  };

  // 关键字搜索
  const searchFile = keyWord => {
    const newFiles = objToArr(files).filter(file => file.title.includes(keyWord));
    setSearchFiles(newFiles);
  };

  // 重命名
  const savaData = (id, newTitle, isNew) => {
    const item = objToArr(files).find(file => file.title === newTitle);
    if (item) {
      newTitle += '_copy';
    }

    const newPath = isNew ? path.join(savedPath, `${newTitle}.md`) : path.join(path.dirname(files[id].path), `${newTitle}.md`);
    const newFile = { ...files[id], title: newTitle, isNew: false, path: newPath };
    const newFiles = { ...files, [id]: newFile };

    if (isNew) {
      // 新建操作
      writeFile(newPath, files[id].body).then(() => {
        setFiles(newFiles);
        saveInfoToStore(newFiles);
      });
    } else {
      // 更新操作
      const oldPath = files[id].path;
      renameFile(oldPath, newPath).then(() => {
        setFiles(newFiles);
        saveInfoToStore(newFiles);
      });
    }
  };

  // 新建操作
  const createFile = () => {
    const newId = v4();
    const newFile = {
      id: newId,
      title: '',
      isNew: true,
      body: '### 初始化内容',
      createTime: new Date().getTime()
    };

    let flag = objToArr(files).find(file => file.isNew);
    if (!flag) {
      // 如果当前有新建文件  点击其他文件需要阻塞
      setFiles({ ...files, [newId]: newFile });
    }
  };

  // 保存正在编辑的文件
  const saveCurrentFile = () => {
    writeFile(activeFile.path, activeFile.body).then(() => {
      setUnSaveIds(unSaveIds.filter(id => id !== activeFile.id));
    });
  };

  // 导入md
  const importFile = () => {
    remote.dialog
      .showOpenDialog({
        buttonLabel: '请选择',
        title: '请选择md文件',
        properties: ['openFile', 'multiSelections'],
        filters: [
          { name: 'md文档', extensions: ['md'] },
          { name: '其他', extensions: ['js', 'json'] }
        ]
      })
      .then(ret => {
        const paths = ret.filePaths;
        if (paths.length) {
          // 判断当前路径 是否已经存在
          const validPaths = paths.filter(filePath => {
            // 判断当前 filepath 是否存在
            const existed = Object.values(files).find(file => file.path === filePath);
            return !existed;
          });
          // 将结果转换成files格式
          const packageData = validPaths.map(filePath => {
            return {
              id: v4(),
              title: path.basename(filePath, '.md'),
              path: filePath
            };
          });
          // 将格式在最终处理一下
          const newFiles = { ...files, ...mapArr(packageData) };
          // 更新
          setFiles(newFiles);
          // 持久化

          // 导入成功
          if (packageData.length) {
            remote.dialog.showMessageBox({
              type: 'info',
              title: '导入md文档',
              message: '文件导入成功'
            });
          }
        } else {
        }
        console.log(ret.filePaths);
      });
  };

  // 主进程与渲染进程的事件通信
  useIpcRenderer({
    'execute-create-file': createFile,
    'execute-import-file': importFile,
    'execute-save-file': saveCurrentFile
  });

  return (
    <div className="App container-fluid px-0">
      <div className="row no-gutters">
        <LeftDiv>
          <SearchFile title="我的文档" onSearch={searchFile} />
          <FileList files={fileList} editFile={openItem} deleteFile={deleteItem} saveFile={savaData} />
          <div className="btn_list">
            <ButtonItem title={'新建'} icon={faPlus} btnClick={createFile}></ButtonItem>
            <ButtonItem title={'导入'} icon={faFileImport} btnClick={importFile}></ButtonItem>
          </div>
        </LeftDiv>
        <RightDiv>
          {activeFile && (
            <>
              <TabList files={openFiles} activeItem={activId} unSaveItems={unSaveIds} clickItem={changeActive} closeItem={closeFile} />
              <SimpleMDE
                key={activeFile.id}
                onChange={value => changeFile(activeFile.id, value)}
                value={activeFile.body}
                options={{
                  autofocus: true,
                  spellChecker: true,
                  minHeight: '750px'
                }}
              />
            </>
          )}
          {!activeFile && <div className="init-page">新建或导入具体的文档</div>}
        </RightDiv>
      </div>
    </div>
  );
}

export default App;

let LeftDiv = styled.div.attrs({
  className: 'col-3 left-panel'
})`
  position: relative;
  background: #7b8c7c;
  min-height: 100vh;

  .btn_list {
    left: 0;
    bottom: 0;
    width: 100%;
    position: absolute;

    p {
      border: 0;
      width: 50%;
      color: #fff;
      border-radius: 0;
      margin-bottom: 0 !important;
    }
    p:nth-of-type(1) {
      background-color: #8ba39e;
    }
    p:nth-of-type(2) {
      background-color: #98b4b3;
    }
  }
`;

let RightDiv = styled.div.attrs({
  className: 'col-9 right-panel'
})`
  background-color: #c9d8cd;
  .init-page {
    color: #888;
    text-align: center;
    font: normal 28px/300px '微软雅黑';
  }
`;
